package buka.oversea.aeron5.config;

import io.aeron.archive.Archive;
import io.aeron.cluster.ConsensusModule;
import io.aeron.cluster.service.ClusteredService;
import io.aeron.cluster.service.ClusteredServiceContainer;
import io.aeron.driver.MediaDriver;
import io.aeron.driver.ThreadingMode;

import java.io.File;

public final class ClusterConfig {

    private static final int PORT_BASE = 9005;
    private static final int PORTS_PER_NODE = 100;

    public static MediaDriver.Context mediaDriver(int nodeId) {
        File base = new File("node" + nodeId);
        base.mkdirs();
        return new MediaDriver.Context()
                .aeronDirectoryName(base.getAbsolutePath() + "/aeron")
                .threadingMode(ThreadingMode.SHARED)
                .dirDeleteOnStart(true);
    }

    public static Archive.Context archive(int nodeId) {
        File base = new File("node" + nodeId);
        return new Archive.Context()
                .aeronDirectoryName(base.getAbsolutePath() + "/aeron")
                .archiveDir(new File(base, "archive"))
                .controlChannel("aeron:udp?endpoint=localhost:" + (PORT_BASE + nodeId * PORTS_PER_NODE + 10));
    }

    public static ConsensusModule.Context consensus(int nodeId) {
        File base = new File("node" + nodeId);
        return new ConsensusModule.Context()
                .clusterMemberId(nodeId)
                .clusterMembers(
                        "0,localhost:9000,localhost:9001,localhost:9002,localhost:9003,localhost:9004|" +
                                "1,localhost:9100,localhost:9101,localhost:9102,localhost:9103,localhost:9104|" +
                                "2,localhost:9200,localhost:9201,localhost:9202,localhost:9203,localhost:9204")
                .clusterDir(new File(base, "cluster"))
                .ingressChannel("aeron:udp?endpoint=localhost:" + (PORT_BASE + nodeId * PORTS_PER_NODE))
                .logChannel("aeron:udp?endpoint=localhost:" + (PORT_BASE + nodeId * PORTS_PER_NODE + 1))
                .replicationChannel("aeron:udp?endpoint=localhost:0");
    }

    public static ClusteredServiceContainer.Context serviceContainerCtx(int nodeId, ClusteredService service) {
        File base = new File("node" + nodeId);
        return new ClusteredServiceContainer.Context()
                .aeronDirectoryName(base.getAbsolutePath() + "/aeron")
                .clusterDir(new File(base, "cluster"))
                .clusteredService(service);
    }
}
